package com.pianzhu.blockchainemr.AOP;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Arrays;
@Aspect
@Component
@Slf4j
public class ControllerAOP {
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Around("execution(* com.pianzhu.blockchainemr.controller..*.*(..))")
    public Object recordTimeAOP(ProceedingJoinPoint pjp) throws Throwable {
        long startTime = System.currentTimeMillis();

        // 记录请求信息
        logRequestInfo(pjp);

        // 执行目标方法
        Object result = pjp.proceed();

        // 记录执行时间
        long endTime = System.currentTimeMillis();
        logJsonResponse(pjp.getSignature().getName(), result, endTime - startTime);
        log.info("方法 {} 执行完成，耗时：{}ms", pjp.getSignature().getName(), endTime - startTime);

        return result;
    }

    private void logRequestInfo(ProceedingJoinPoint pjp) {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes == null) return;

            HttpServletRequest request = attributes.getRequest();
            MethodSignature signature = (MethodSignature) pjp.getSignature();

            log.info("=== 请求信息 ===");
            log.info("URL: {} {}", request.getMethod(), request.getRequestURL());
            log.info("方法: {}.{}", pjp.getTarget().getClass().getSimpleName(), signature.getName());
            log.info("参数: {}", Arrays.toString(pjp.getArgs()));
            log.info("==============");


        } catch (Exception e) {
            log.warn("记录请求信息失败: {}", e.getMessage());
        }
    }

    private void logJsonResponse(String methodName, Object result, long executionTime) {
        try {
            if (result != null) {
                String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(result);
                log.info("方法 {} - {}ms\n返回JSON:\n{}", methodName, executionTime, json);
            } else {
                log.info("方法 {} - {}ms\n返回JSON: null", methodName, executionTime);
            }
        } catch (Exception e) {
            log.info("方法 {} - {}ms\n返回数据: {}", methodName, executionTime, result);
        }
    }
}